




#include "arch.h"
#include "A.utilities"

//user program



class Root_proc: public Thread{

   public:

        Root_proc()
                : Thread((Tmf0_ptr)&Root_proc::body){}

        void body(){

            fprintf(Sdf::trace, "node %d, in Root_proc::starts\n", Sdf::PROC_ID);
            fflush(Sdf::trace);

            int sendarray[12];
            sendarray[0]  = 1;
            sendarray[1]  = 2;
            sendarray[2]  = 3;
            sendarray[3]  = 4;
            sendarray[4]  = 5;
            sendarray[5]  = 6;
            sendarray[6]  = 7;
            sendarray[7]  = 8;
            sendarray[8]  = 9;
            sendarray[9]  = 10;
            sendarray[10] = 11;
            sendarray[11] = 12;

              //2 integers separated by 2 integers
            MPI_Datatype stype;
            MPI_Type_vector(2, 1, 3, MPI_INT, &stype);
            MPI_Type_commit(&stype);

            int spack_size;
            MPI_Pack_size(3, stype, 
                          MPI_COMM_WORLD, &spack_size);
            char *sbuf = new char[spack_size];

            int recvarray[6];
              //4 contiguous integers
            MPI_Datatype rtype;
            MPI_Type_vector(6, 1, 1, MPI_INT, &rtype);
            MPI_Type_commit(&rtype);

            int rpack_size;
            MPI_Pack_size(1, rtype, 
                          MPI_COMM_WORLD, &rpack_size);
            char *rbuf = new char[rpack_size];

            fprintf(Sdf::trace, "node %d, @@@@1 spack_size=%d, rpack_size=%d\n", 
                    Sdf::PROC_ID, spack_size,rpack_size);
            fflush(Sdf::trace);

            int position = 0;
            MPI_Pack(sendarray, 3, stype,
                     sbuf, spack_size, &position, MPI_COMM_WORLD);

            MPI_Status status;

            if(!Sdf::PROC_ID){
               MPI_Send(sbuf,spack_size, MPI_CHAR, 1, 0, MPI_COMM_WORLD);
            }else{
               MPI_Recv(rbuf, rpack_size, MPI_CHAR, 0, 0, MPI_COMM_WORLD, &status);

               char *rbuf1 = new char[rpack_size];

               position = 0;
               MPI_Unpack(rbuf, rpack_size, &position, 
                          rbuf1, rpack_size, MPI_PACKED,
                          MPI_COMM_WORLD);

               int pack_size;
               MPI_Pack_size(rpack_size, MPI_PACKED, 
                             MPI_COMM_WORLD, &pack_size);

               fprintf(Sdf::trace, "node %d, @@@@2 pack_size=%d\n", 
                    Sdf::PROC_ID, pack_size);
               fflush(Sdf::trace);

               position = 0;
               MPI_Unpack(rbuf1, rpack_size, &position, 
                          recvarray, 1, rtype,
                          MPI_COMM_WORLD);
               fprintf(Sdf::trace, "node %d, ####1 result=%d, %d, %d, %d, %d, %d\n", 
                       Sdf::PROC_ID, 
                       recvarray[0],recvarray[1],
                       recvarray[2],recvarray[3],
                       recvarray[4],recvarray[5]);
               fflush(Sdf::trace);
            }

            fprintf(Sdf::trace, "node %d, in Root_proc::finishes\n", Sdf::PROC_ID);
            fflush(Sdf::trace);
        }
};
//end of user program

MAIN(Root_proc, Sdf::empty, Sdf::empty, Sdf::empty)



